public with sharing class MC_New_Old_SignupsController
{
    public Id MissionalCommunityId {get; set;}
    public Id ContactId {get; set;}
    
    public Contact Recipient
    {
        get
        {
            if(Recipient==null)
                Recipient=[select Id, Email from Contact where Id=:ContactId];
            return Recipient;
        }
        
        set;
    }
    
    public List<Missional_Community_Member__c> NewMembers
    {
        get
        {
            if(NewMembers==null)
                NewMembers=GetMembers(true);
            
            return NewMembers;
        }
        
        set;
    }
    
    public List<Missional_Community_Member__c> OldMembers
    {
        get
        {
            if(OldMembers==null)
                OldMembers=GetMembers(false);
            
            return OldMembers;
        }
        
        set;
    }
    
    public Integer NumNewMembers
    {
        get
        {
            if(NewMembers==null)
                return 0;
            return NewMembers.size();
        }
    }
    
    public Integer NumOldMembers
    {
        get
        {
            if(OldMembers==null)
                return 0;
            return OldMembers.size();
        }
    }
    
    public List<Missional_Community_Member__c> UncontactedMembers
    {
        get
        {
            if(UncontactedMembers==null)
                UncontactedMembers=GetAllUncontactedMembers();
            return UncontactedMembers;
        }
        
        set;
    }
    
    public String AllUncontactedEmails
    {
        get
        {
            if(AllUncontactedEmails==null)
            {
                String emails='';
                for(Missional_Community_Member__c member : UncontactedMembers)
                    if(member.Contact__r.Email!=null)
                    {
                        if(emails.length()>0)
                            emails=emails+',';
                        emails=emails+member.Contact__r.Email;
                    }
                AllUncontactedEmails=emails;
            }
            return AllUncontactedEmails;
        }
        
        set;
    }
    
    public Integer NumUncontactedMembers
    {
    	get
    	{
    		if(UncontactedMembers==null)
    			return 0;
    		return UncontactedMembers.size();
    	}
    }
    
    public List<Missional_Community_Member__c> OtherLeaders
    {
        get
        {
            if(OtherLeaders==null)
                OtherLeaders=FindOtherLeaders();
            return OtherLeaders;
        }
        
        set;
    }
    
    public String OtherLeaderEmails
    {
        get
        {
            String emails='';
            for(Missional_Community_Member__c otherLeader : OtherLeaders)
            {
                if(otherLeader.Contact__r.Email!=null)
                {
                    if(emails.length()>0)
                        emails=emails+',';
                    emails=emails+otherLeader.Contact__r.Email;
                }
            }
            OtherLeaderEmails=emails;
            return OtherLeaderEmails;
        }
        
        set;
    }
    
    //XYZZY Hardcoded constants. Replace with configuration options
    public String SalesforceEmailSingle { get {return 'contactverification@austinstone.org';} }
    public String SalesforceEmailAll { get {return 'contactverificationall@austinstone.org';} }
    public String AlreadyContactedPublicPage { get {return 'http://force.austinstone.org/MC_AlreadyContacted'; } }
    
    private List<Missional_Community_Member__c> GetMembers(Boolean find_new_members)
    {
        List<Missional_Community_Member__c> ret;
        DateTime afterTime;
        DateTime beforeTime;
        if(find_new_members)
        {
            afterTime=DateTime.now().addDays(-1);
            beforeTime=DateTime.valueOfGmt('4000-12-31 00:00:00');
        }
        else
        {
            beforeTime=DateTime.now().addDays(-1);
            afterTime=DateTime.valueOfGmt('1700-01-01 00:00:00');
        }
            
        ret=
        [
            select
                id
                ,contact__r.Name
                ,contact__r.gender__c
                ,contact__r.Phone
                ,contact__r.Email
            from
                Missional_Community_Member__c
            where
                missional_community__c=:MissionalCommunityId
                and role__c<>'Leader'
                and has_been_contacted__c=false
                and date_joined__c > :afterTime
                and date_joined__c <= :beforeTime
            order by
                date_joined__c
        ];
        
        return ret;
    }
    
    private List<Missional_Community_Member__c> GetAllUncontactedMembers()
    {
        List<Missional_Community_Member__c> ret;
        
        ret=
        [
            select
                id
                ,contact__r.Email
            from
                Missional_Community_Member__c
            where
                missional_community__c=:MissionalCommunityId
                and role__c<>'Leader'
                and has_been_contacted__c=false
        ];
        
        return ret;
    }
    
    private List<Missional_Community_Member__c> FindOtherLeaders()
    {
        List<Missional_Community_Member__c> ret;
        
        ret=
        [
            select
                id
                ,contact__r.Email
            from
                Missional_Community_Member__c
            where
                missional_community__c=:MissionalCommunityId
                and contact__c<>:ContactId
                and role__c='Leader'
        ];
        
        return ret;
    }
    
    public static testmethod void Test1()
    {
    	//Put together some test data
    	Missional_Community__c aGroup=new Missional_Community__c();
    	Contact aLeader=new Contact();
    	aLeader.AccountId=[select id from Account where Name='Missional Community Members' limit 1].Id;
    	aLeader.FirstName='LeaderFirst';
    	aLeader.LastName='LeaderLast';
    	aLeader.Email='leader@email.bad';
    	insert aGroup;
    	insert aLeader;
    	Missional_Community_Member__c aGroupMember=new Missional_Community_Member__c();
    	aGroupMember.Contact__c=aLeader.Id;
    	aGroupMember.Missional_Community__c=aGroup.Id;
    	aGroupMember.Role__c='Leader';
    	insert aGroupMember;
    	
    	Contact aMember1=new Contact();
    	aMember1.AccountId=[select id from Account where Name='Missional Community Members' limit 1].Id;
    	aMember1.FirstName='Member1First';
    	aMember1.LastName='Member1Last';
    	aMember1.Email='member1@email.bad';
    	insert aMember1;
    	Missional_Community_Member__c aGroupMember2=new Missional_Community_Member__c();
    	aGroupMember2.Contact__c=aMember1.Id;
    	aGroupMember2.Missional_Community__c=aGroup.Id;
    	aGroupMember2.Role__c='Member';
    	aGroupMember2.Date_Joined__c=DateTime.now().addDays(-1).addHours(-5);
    	insert aGroupMember2;
    	
    	Contact aMember2=new Contact();
    	aMember2.AccountId=[select id from Account where Name='Missional Community Members' limit 1].Id;
    	aMember2.FirstName='Member2First';
    	aMember2.LastName='Member2Last';
    	aMember2.Email='member2@email.bad';
    	insert aMember2;
    	Missional_Community_Member__c aGroupMember3=new Missional_Community_Member__c();
    	aGroupMember3.Contact__c=aMember2.Id;
    	aGroupMember3.Missional_Community__c=aGroup.Id;
    	aGroupMember3.Role__c='Member';
    	aGroupMember3.Date_Joined__c=DateTime.now().addHours(-5);
    	insert aGroupMember3;


		MC_New_Old_SignupsController controller=new MC_New_Old_SignupsController();
		controller.ContactId=aLeader.id;
		controller.MissionalCommunityId=aGroup.id;
		
		Boolean oldFoundPositive=false;
		Boolean oldFoundNegative=false;
		for(Missional_Community_Member__c member : controller.OldMembers)
		{
			if(member.id==aGroupMember2.id)
				oldFoundPositive=true;
			if(member.id==aGroupMember.id)
				oldFoundNegative=true;
			if(member.id==aGroupMember3.id)
				oldFoundNegative=true;
		}
		System.assertEquals(true, oldFoundPositive);
		System.assertEquals(false, oldFoundNegative);
		System.assert(controller.NumOldMembers>0);
		
		Boolean newFoundPositive=false;
		Boolean newFoundNegative=false;
		for(Missional_Community_Member__c member : controller.NewMembers)
		{
			if(member.id==aGroupMember3.id)
				newFoundPositive=true;
			if(member.id==aGroupMember.id)
				newFoundNegative=true;
			if(member.id==aGroupMember2.id)
				newFoundNegative=true;
		}
		System.assertEquals(true, newFoundPositive);
		System.assertEquals(false, newFoundNegative);
		System.assert(controller.NumNewMembers>0);
		
		String uncontactedEmails=controller.AllUncontactedEmails;
		System.assert(uncontactedEmails.contains(aMember1.Email));
		System.assert(uncontactedEmails.contains(aMember2.Email));
		System.assert(!uncontactedEmails.contains(aLeader.Email));
		System.assert(controller.NumUncontactedMembers>0);
		
		Contact aLeader2=new Contact();
    	aLeader2.AccountId=[select id from Account where Name='Missional Community Members' limit 1].Id;
    	aLeader2.FirstName='Leader2First';
    	aLeader2.LastName='Leader2Last';
    	aLeader2.Email='leader2@email.bad';
    	insert aLeader2;
  		
  		Missional_Community_Member__c aGroupMember4=new Missional_Community_Member__c();
    	aGroupMember4.Contact__c=aLeader2.Id;
    	aGroupMember4.Missional_Community__c=aGroup.Id;
    	aGroupMember4.Role__c='Leader';
    	insert aGroupMember4;
    	
 		String otherLeaderEmails=controller.OtherLeaderEmails;
 		System.assert(otherLeaderEmails.contains(aLeader2.Email));
 		System.assert(!otherLeaderEmails.contains(aLeader.Email));   			
    }
}